package com.globalwave.common;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * User: JinBo Date: 2006-4-6 Time: 11:27:00
 */
public class PublicUtils {

    /**
     * 将java.sql.Date类型的日期转换为yyyy-MM-dd格式日期字符串 注：只有日期
     * 
     * @author mys
     */
    public static String sqlDateToStr(java.sql.Date date) {
        return formatSqlDate(date, "yyyy-MM-dd");
    }

    /**
     * 将java.sql.Date类型的日期转换为pattern格式的日期字符串
     * 
     * @author mys
     */
    public static String formatSqlDate(java.sql.Date date, String pattern) {
        if (date == null)
            return "";
        DateFormat format = new SimpleDateFormat(pattern);
        return format.format(date);
    }

    /**
     * 将yyyy-MM-dd格式的日期字符串转换为java.sql.Date类型
     * 
     * @author mys
     * @throws Exception
     */
    public static java.sql.Date strToSqlDate(String datetime) throws Exception {
        return strToSqlDate(datetime, "yyyy-MM-dd");
    }

    /**
     * 将pattern格式的日期字符串转换为java.sql.Date类型
     * 
     * @author mys
     * @throws Exception
     */
    public static java.sql.Date strToSqlDate(String datetime, String pattern)
            throws Exception {
        java.sql.Date result = null;
        try {
            if ((datetime != null) && (datetime.length() > 0)) {
                SimpleDateFormat format = new SimpleDateFormat(pattern);
                result = new java.sql.Date(format.parse(datetime).getTime());
            }
        } catch (Exception exp) {
            throw new Exception("have a NG date format");
        }
        return result;
    }

    /**
     * 将java.utils.Date类型的日期转换为“yyyy-MM-dd HH:mm:ss" 格式日期字符串<br>
     * 注：只有日期，时，分，秒为零
     */
    public static String utilDateToStr(java.util.Date date) {
        return formatUtilDate(date, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 将java.utils.Date类型的日期转换为pattern格式的日期字符串
     */
    public static String formatUtilDate(java.util.Date date, String pattern) {
        if (date == null)
            return "";
        DateFormat format = new SimpleDateFormat(pattern);
        return format.format(date);
    }

    /**
     * xqy 将“yyyy-MM-dd HH:mm:ss"格式的日期字符串转换为java.utils.Date类型
     * 
     * @throws Exception
     */
    public static java.util.Date UtilStrToDate(String datetime)
            throws Exception {
        return UtilStrToDate(datetime, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * xqy 将pattern格式的日期字符串转换为java.utils.Date类型
     * 
     * @throws Exception
     */
    public static java.util.Date UtilStrToDate(String datetime, String pattern)
            throws Exception {
        java.util.Date result;
        try {
            if ((datetime != null) && (datetime.length() > 0)) {
                SimpleDateFormat format = new SimpleDateFormat(pattern);
                result = format.parse(datetime);
            } else {
                result = null;
            }
        } catch (Exception exp) {
            // 指定的日期字符串格式不对
            throw new Exception("have a NG date format");
        }
        return result;
    }

    /**
     * 将对象强制转换为字符串，空则返回""
     */
    public static String objToStr(Object obj) {
        if (obj != null)
            return obj.toString();
        return "";
    }

    /**
     * 比较两个日期相差多少个月，用d2 - d1
     */
    public static int compareMonth(java.util.Date d1, java.util.Date d2) {
        java.util.Calendar c1 = java.util.Calendar.getInstance();
        c1.setTime(d1);
        java.util.Calendar c2 = java.util.Calendar.getInstance();
        c2.setTime(d2);
        // int m1 = c1.get(java.utils.Calendar.YEAR) * 12 +
        // c1.get(java.utils.Calendar.MONTH);
        // int m2 = c2.get(java.utils.Calendar.YEAR) * 12 +
        // c2.get(java.utils.Calendar.MONTH);

        return (c1.get(java.util.Calendar.YEAR) - c2
                .get(java.util.Calendar.YEAR))
                * 12
                + (c1.get(java.util.Calendar.MONTH) - c2
                        .get(java.util.Calendar.MONTH));
    }

    /**
     * 比较两个日期相差多少个月，用d2 - d1
     * 
     * @author mys
     */
    public static int compareMonth(java.sql.Date d1, java.sql.Date d2) {
        java.util.Calendar c1 = java.util.Calendar.getInstance();
        c1.setTime(d1);
        java.util.Calendar c2 = java.util.Calendar.getInstance();
        c2.setTime(d2);

        return (c1.get(java.util.Calendar.YEAR) - c2
                .get(java.util.Calendar.YEAR))
                * 12
                + (c1.get(java.util.Calendar.MONTH) - c2
                        .get(java.util.Calendar.MONTH));
    }

    /**
     * 验证目标字符串是否整数
     * <p>
     * PublicUtils.isInteger(null) = false
     * <p>
     * PublicUtils.isInteger("") = false
     * <p>
     * PublicUtils.isInteger(" ") = false
     * <p>
     * PublicUtils.isInteger("02007") = false
     * <p>
     * PublicUtils.isInteger("2 007") = false
     * <p>
     * PublicUtils.isInteger(" 2007 ") = true
     * <p>
     * 
     * @param str
     *            要验证的字符串
     * @return
     */
    public static boolean isInteger(String str) {
        Pattern pattern = Pattern.compile("([1-9]+[0-9]*|0)");
        Matcher matcher = pattern.matcher(org.apache.commons.lang.StringUtils
                .trimToEmpty(str));
        return matcher.matches();
    }

    /**
     * 验证目标字符串是否小数
     * 
     * @param str
     *            要验证的字符串
     * @param scale
     *            精度，即小数点后几位
     * @param maximum
     *            最大值（小于maxinum）
     * @return
     */
    public static boolean isDecimal(String str, int scale, double maximum) {
        Pattern pattern = Pattern.compile("([1-9]+[0-9]*|0)(\\.[0-9]{1,"
                + scale + "}|)");
        Matcher matcher = pattern.matcher(org.apache.commons.lang.StringUtils
                .trimToEmpty(str));
        return matcher.matches() && Double.parseDouble(str) <= maximum;
    }

    /**
     * 用于将小写金额转换成大写，最大数据为亿
     * 
     * @param value
     *            小写金额（精确到小数点后两位）
     * @return 大写金额
     * @throws IllegalArgumentException
     *             当传入参数为空或者不是有效数字类型时，抛出该例外
     */
    public static String changeToBig(String value) {
        if (org.apache.commons.lang.StringUtils.isBlank(value)) {
            throw new IllegalArgumentException("传入方法 PublicUtils.changeToBig("
                    + "String value)的参数不允许为空：" + value + "。");
        }
        if (!isDecimal(value, 2, 99999999)) {
            throw new IllegalArgumentException("传入方法 PublicUtils.changeToBig("
                    + "String value)的参数不是有效数字：" + value + "。");
        }
        BigDecimal d = new BigDecimal(value);
        BigDecimal d2 = new BigDecimal("100");
        char[] hunit = { '拾', '佰', '仟' }; // 段内位置表示
        char[] vunit = { '万', '亿' }; // 段名表示
        char[] digit = { '零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖' }; // 数字表示
        long midVal = 0;
        String valStr = "";
        String head = "";
        String rail = "";
        if (d.compareTo(new BigDecimal("1")) < 0) {
            head = "0";
            rail = d.multiply(new BigDecimal("100")).compareTo(
                    new BigDecimal("10")) < 0 ? "0"
                    + (d.multiply(d2).toString()) : d.multiply(d2).toString();
        } else {
            midVal = d.multiply(new BigDecimal("100")).longValue(); // 转化成整形
            valStr = String.valueOf(midVal); // 转化成字符串
            head = valStr.substring(0, valStr.length() - 2); // 取整数部分
            rail = valStr.substring(valStr.length() - 2); // 取小数部分
        }

        String prefix = ""; // 整数部分转化的结果
        String suffix = ""; // 小数部分转化的结果
        // 处理小数点后面的数
        if (rail.equals("00")) { // 如果小数部分为0
            suffix = "整";
        } else {
            suffix = digit[rail.charAt(0) - '0'] + "角"
                    + digit[rail.charAt(1) - '0'] + "分"; // 否则把角分转化出来
        }
        // 处理小数点前面的数
        char[] chDig = head.toCharArray(); // 把整数部分转化成字符数组
        char zero = '0'; // 标志'0'表示出现过0
        byte zeroSerNum = 0; // 连续出现0的次数
        for (int i = 0; i < chDig.length; i++) { // 循环处理每个数字
            int idx = (chDig.length - i - 1) % 4; // 取段内位置
            int vidx = (chDig.length - i - 1) / 4; // 取段位置
            if (chDig[i] == '0') { // 如果当前字符是0
                zeroSerNum++; // 连续0次数递增
                if (zero == '0') { // 标志
                    zero = digit[0];
                } else if (idx == 0 && vidx > 0 && zeroSerNum < 4) {
                    prefix += vunit[vidx - 1];
                    zero = '0';
                }
                continue;
            }
            zeroSerNum = 0; // 连续0次数清零
            if (zero != '0') { // 如果标志不为0,则加上,例如万,亿什么的
                prefix += zero;
                zero = '0';
            }
            prefix += digit[chDig[i] - '0']; // 转化该数字表示
            if (idx > 0)
                prefix += hunit[idx - 1];
            if (idx == 0 && vidx > 0) {
                prefix += vunit[vidx - 1]; // 段结束位置应该加上段名如万,亿
            }
        }

        if (prefix.length() > 0)
            prefix += '圆'; // 如果整数部分存在,则有圆的字样
        return prefix + suffix; // 返回正确表示
    }

    /**
     * 将整数或者小数转换成字符串
     * 
     * @param value
     *            待转换的有效数字
     * @return
     * @throws IllegalArgumentException
     *             当传入参数为空或者不是有效数字类型时，抛出该例外
     */
    public static char[] changeToArray(String value) {
        if (org.apache.commons.lang.StringUtils.isBlank(value)) {
            throw new IllegalArgumentException(
                    "传入方法 PublicUtils.changeToArray("
                            + "String value)的参数不允许为空：" + value + "。");
        }
        if (!isDecimal(value, 2, 99999999)) {
            throw new IllegalArgumentException(
                    "传入方法 PublicUtils.changeToArray("
                            + "String value)的参数不是有效数字：" + value + "。");
        }
        BigDecimal d = new BigDecimal(value);
        long midVal = d.multiply(new BigDecimal("100")).longValue();
        String tmp = String.valueOf(midVal);
        char[] chs = tmp.toCharArray();
        return chs;
    }
}
